﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Peninsula.Common.Log
{
   public  interface ILogger
    {

        void Log(LogLevel level, IFormatProvider formatProvider, string message, params object[] args);
    }


    public static class ILoggerExtensions
    {
        /// <summary>
        /// 递归记录日志信息
        /// </summary>
        public static void LogException(this ILogger logger, string title, Exception exception)
        {
            string error = "";
            GetExceptionInfos(exception, out error);
            ILoggerExtensions.Error(logger, title + "\r\nDetail:\r\n" + exception);
        }

        /// <summary>
        /// 递归记录日志信息
        /// </summary>
        public static void LogException(this ILogger logger, Exception exception)
        {
            LogException(logger, "", exception);
        }

        /// <summary>
        /// 递归打印所有异常信息
        /// </summary>
        /// <param name="ex"></param>
        public static void GetExceptionInfos(Exception ex, out string exMessage)
        {
            exMessage = string.IsNullOrWhiteSpace(ex.Message)
                            ? ex.Message
                            : "\r\n\r\n" + ex.Message;
            exMessage += "\r\n\r\n" + ex.StackTrace;
            if (ex.InnerException != null)
            {
                GetExceptionInfos(ex.InnerException, out exMessage);
            }
        }

        #region Trace() overloads

        public static void EnableTrace(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Trace, enabled);
        }

        public static void Trace(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Trace, formatProvider, message, args);
        }

        public static void Trace(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Trace, null, message, null);
        }

        public static void Trace(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Trace, null, message, args);
        }

        #endregion

        #region Debug() overloads

        public static void EnableDebug(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Debug, enabled);
        }

        public static void Debug(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Debug, formatProvider, message, args);
        }

        public static void Debug(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Debug, null, message, null);
        }

        public static void Debug(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Debug, null, message, args);
        }

        #endregion

        #region Info() overloads

        public static void EnableInfo(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Info, enabled);
        }

        public static void Info(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Info, formatProvider, message, args);
        }

        public static void Info(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Info, null, message, null);
        }

        public static void Info(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Info, null, message, args);
        }

        #endregion

        #region Warn() overloads

        public static void EnableWarn(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Warn, enabled);
        }

        public static void Warn(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Warn, formatProvider, message, args);
        }

        public static void Warn(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Warn, null, message, null);
        }

        public static void Warn(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Warn, null, message, args);
        }

        #endregion

        #region Error() overloads

        public static void EnableError(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Error, enabled);
        }

        public static void Error(this ILogger logger, Exception exception)
        {
            string message = "";
            GetExceptionInfos(exception, out message);
            logger.Log(LogLevel.Error, null, message, null);
        }

        public static void Error(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Error, formatProvider, message, args);
        }

        public static void Error(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Error, null, message, null);
        }

        public static void Error(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Error, null, message, args);
        }


        #endregion

        #region Fatal() overloads

        public static void EnableFatal(this ILoggerManager loggerManager, bool enabled)
        {
            loggerManager.EnableLogLevel(LogLevel.Fatal, enabled);
        }

        public static void Fatal(this ILogger logger, Exception exception)
        {
            string message = "";
            GetExceptionInfos(exception, out message);
            logger.Log(LogLevel.Fatal, null, message, null);
        }

        public static void Fatal(this ILogger logger, IFormatProvider formatProvider, string message, params object[] args)
        {
            logger.Log(LogLevel.Fatal, formatProvider, message, args);
        }

        public static void Fatal(this ILogger logger, string message)
        {
            logger.Log(LogLevel.Fatal, null, message, null);
        }

        public static void Fatal(this ILogger logger, string message, params object[] args)
        {
            logger.Log(LogLevel.Fatal, null, message, args);
        }

        #endregion
    }
}
